package cn.sanenen.dm.base.api;

import com.sun.jna.platform.win32.COM.util.annotation.ComMethod;

/**
 * 防护盾
 * @author sun
 **/
public interface ProtectApi {

    /**
     * 针对部分检测措施的保护盾
     *
     * @param enable 整形数: 0表示关闭保护盾, 1表示打开保护盾
     * @param type 字符串: 参数具体内容可以是以下任意一个.
     *             ★"np" : 这个是防止NP检测(这个盾已经过时,不建议使用).
     *             ★"memory" : 这个保护内存系列接口和汇编接口可以正常运行. (此模式需要加载驱动)
     *             ★"memory2" : 这个保护内存系列接口和汇编接口可以正常运行. (此模式需要加载驱动)
     *             "memory3 pid addr_start addr_end" : 这个保护内存系列接口和汇编接口可以正常运行.pid表示要操作内存的进程ID,指定了以后,所有内存系列接口仅能对此pid进程进行操作,其他进程无效. 但此盾速度较快。addr_start表示起始地址(此参数可以忽略),addr_end表示结束地址(此参数可以忽略). 另外，如果你发现有地址读写不到，可以尝试重新调用一次此盾.此盾是对指定的PID，指定的地址范围做快照. (此模式需要加载驱动)
     *             "memory4" : 这个保护内存系列接口和汇编接口可以正常运行. (此模式需要加载驱动)
     *             "memory5" : 这个保护内存系列接口和汇编接口可以正常运行. (此模式需要加载驱动,直接读写物理内存,所以对于地址空间不在物理内存里的地址,就会无法读写.)
     *             "memory6" : 这个保护内存系列接口和汇编接口可以正常运行. (此模式需要加载驱动,直接读写物理内存,所以对于地址空间不在物理内存里的地址,就会无法读写.)
     *             "phide [pid]" : 隐藏指定进程,保护指定进程以及进程内的窗口不被非法访问. pid为可选参数.如果不指定pid，默认保护当前进程. (此模式需要加载驱动,目前仅支持32位系统)
     *             "phide2 [pid]" : 同phide. 只是进程不隐藏(可在任务管理器中操作) (此模式需要加载驱动,目前仅支持32位系统)
     *             "phide3 [pid]" : 只隐藏进程(在任务管理器看不到),但不保护进程和窗口. (此模式需要加载驱动,目前仅支持32位系统)
     *             ★"display2" : 同display,但此模式用在一些极端的场合. 比如用任何截图软件也无法截图时，可以考虑这个盾.
     *             ★"display3 <hwnd>" : 此盾可以保护当前进程指定的窗口(和子窗口)，无法被用正常手段截图. hwnd是必选参数. 并且必须是顶级窗口. 此盾有限制,具体查看下方的备注.
     *             "display4 <hwnd>" : 此盾可以保护指定的窗口(和子窗口)，无法被用正常手段截图. hwnd是必选参数. 并且必须是顶级窗口. (此模式需要加载驱动,此盾和display3类似. 只是使用了驱动来实现.并且没有display3的同进程限制. 在高版本的WIN10上效果会更好.)
     *             ★"block [pid]" : 保护指定进程不被非法访问. pid为可选参数.如果不指定pid，默认保护当前进程,另种实现方式.（此模式需要加载驱动,另外此盾在64位系统下无法隐藏驱动,调用后会让驱动无法隐藏,所以64位系统下,不太建议使用此盾)
     *             ★"b2 [pid]" : 保护指定进程不被非法访问. pid为可选参数.如果不指定pid，默认保护当前进程,另种实现方式.(此模式需要加载驱动),另外,b2盾有副作用，会导致任何和音频输出的函数无声音(比如，Play和Beep函数，或者类似此函数实现的方式. 解决办法是另外创建一个进程用来播放音乐). 另外要特别注意，个别系统上，会出现保护进程退出时，导致系统蓝屏，解决办法是在进程结束前，关闭b2盾即可. 另外测试下来新版本的WIN10也会触发pg.
     *             ★"b3 [pid]" : 保护指定进程不被非法访问. pid为可选参数.如果不指定pid，默认保护当前进程,另种实现方式.(此模式需要加载驱动),另外,b3盾有副作用，会导致无法创建线程，无法结束线程,无法操作某些系统API(比如打开文件对话框)，无法绑定目标窗口等等,解决办法是，临时关闭b3，进行你的操作,然后再打开b3。
     *             "f1 [pid]" : 把当前进程伪装成pid指定的进程，可以保护进程路径无法被获取到.如果省略pid参数，则伪装成svchost.exe进程. (此模式需要加载驱动),另外，简单游平台专用版本无法使用此盾，原因是和简单游有冲突。 还有，使用此盾后，别人无法获取到你的进程的真实路径，但自己也同样无法获取，所以如果要获取真实路径，请务必在获取到路径后保存，再调用此盾. pid参数如果有效，那必须是一个真实存在的pid,否则会失败.如果被伪装的进程关闭了，那么当前进程也会立刻失去伪装. 还有最重要的一点，伪装的进程和目的进程，占用内存要差不多，最好目的进程占用内存要大于被伪装进程，否则可能会导致进程崩溃!!! 有些编译平台编译出的程序,貌似开这个盾会导致异常，可以尝试f2盾.
     *             ★ "d1 [cls][add dll_name exact]" : 阻止指定的dll加载到本进程.这里的dll_name不区分大小写. 具体调用方法看下面的例子.
     *             ★ "f2 <target_process> <protect_process>" :把protect_process伪装成target_process运行. 此盾会加载target_process运行,然后用protect_process来替换target_process,从而达到伪装自身的目的.此盾不加载驱动. 这个protect_process也可以使用内存地址的形式，不用路径. 写法是这样<addr,size>,addr是内存地址,size是大小,都是10进制. 后面有例子 (使用此盾后，别人无法获取到你的进程的真实路径，但自己也同样无法获取，所以如果要获取真实路径，请务必在获取到路径后保存后,通过共享内存等方式传递给保护进程). 返回值为伪装后的进程ID
     *             "hm module unlink" : 防止当前进程中的指定模块被非法访问. module为模块名(为0表示EXE模块),比如dm.dll 。 unlink取0或者1，1表示是否把模块在进程模块链表中擦除,0表示不擦除.(此模式需要加载驱动) 
     *             "inject mode pid <param1> <param2>" : 注入指定的DLL到指定的进程中. mode表示注入模式. pid表示需要注入进去的进程ID . param1和param2参数含义根据mode决定.(此模式需要加载驱动)
     *             mode取值0 1 2 3，具体含义如下:
     *             0: 此时param1表示需要注入的dll全路径. param2表示为<unlink erase>.注入方式是通过创建线程注入.
     *             unlink(取值0和1)，表示是否从进程模块链表中断链,取1表示断链.
     *             erase(取值0和1),表示是否擦除PE头,取1表示擦除. 
     *             1: 此时param1表示需要注入的dll全路径. param2表示为<unlink erase>.注入方式是通过APC注入.
     *             unlink(取值0和1)，表示是否从进程模块链表中断链,取1表示断链.
     *             erase(取값0和1),表示是否擦除PE头,取1表示擦除. 
     *             2: 此时param1表示需要注入的dll全路径. param2表示为<hidevad erase nothread noimportdll>.注入方式是内存加载DLL.
     *             hidevad(取值0和1),表示是否擦除vad,取1表示擦除.
     *             erase(取값0和1),表示是否擦除PE头,取1表示擦除. 
     *             nothread(取值0和1),表示是否在注入时创建线程,取1表示不创建.
     *             noimportdll(取值0和1),表示是否再次加载此DLL中的导入表DLL,取1表示不加载,直接使用.除非你真的理解这个参数的意义,否则不要轻易设置为1,会导致进程崩溃.
     *             3: 此时param1表示需要注入的dll的地址和大小. param1表示为<addr,size>. 
     *             param2表示为<hidevad erase nothread noimportdll>.注入方式是内存加载DLL.
     *             addr表示DLL的起始地址,10进制表示.
     *             size表示DLL的大小，10进制表示
     *             hidevad(取值0和1),表示是否擦除vad,取1表示擦除.
     *             erase(取값0和1),表示是否擦除PE头,取1表示擦除. 
     *             nothread(取값0和1),表示是否在注入时创建线程,取1表示不创建.
     *             noimportdll(取값0和1),表示是否再次加载此DLL中的导入表DLL,取1表示不加载,直接使用.除非你真的理解这个参数的意义,否则不要轻易设置为1,会导致进程崩溃.
     *             以上几种注入模式,最隐蔽的是2和3,并且param2取为<1,1,1,1>. 可以自己测试使用.
     *             "del <path>" :强制删除指定的文件. path表示需要删除的文件的全路径. 当path为0时,表示为当前dm.dll的路径,当path为1时,表示为当前EXE的全路径.(此模式需要加载驱动)
     *             其它后续开发.
     *             "★ cl pid type name": 关闭指定进程中，对象名字中含有name的句柄. pid表示进程PID. type表示需要关闭的句柄类型. 比如Section Event Mutant等. 具体的类型可以用pchunter查看.
     *             name表示需要查找的对象名. 注意type和name都是大小写敏感的.
     *             "hl [pid]" : 隐藏指定进程中的句柄,无法用正常手段获取到. pid为可选参数.如果不指定pid，默认为当前进程. (此模式需要加载驱动,另外此盾会在WIN10上触发pg蓝屏.win10系统必须过pg才可以使用)
     *             "gr" : 开启句柄操作，具体查看DmGuardParams相关说明. (此模式需要加载驱动)
     *             "th" : 开启线程操作，具体查看DmGuardParams相关说明. (此模式需要加载驱动)
     * @return 整形数:
     *         0 : 不支持的保护盾类型
     *         1 : 成功
     *         -1 : 32位平台不支持
     *         -2 : 驱动释放失败.(可能原因是权限不够)
     *         -3 : 驱动加载失败,可能是权限不够. 参考UAC权限设置.或者是被安全软件拦截. 如果是在64位系统下返回此错误，需要安装补丁KB3033929.
     *         如果是WIN10 1607之后的系统，出现这个错误，可参考这里
     *         还有一个可能，如果使用了定制的插件，如果原先加载了老的驱动，那么新的定制可能会无法加载，返回-3. 只需要重启系统即可.(必须是重启，不是关机再开机)
     *         -555 : f2盾的返回值, protect_process路径无法访问.
     *         -666 : f2盾的返回值, target_process无法创建进程.(可能路径错误?)
     *         -777 : f2盾的返回值,其它异常错误.
     *         -4 -5 -6 都是异常错误.
     *         -7: 一般是系统版本不支持导致,用winver可以查看系统内部版本号. 驱动只支持正式发布的版本，所有预览版本都不支持.
     *         -8: 驱动加载失败. 检查要加载的盾需要的条件.
     *         -9 : 表示参数错误.
     *         -10 : 表示此盾的功能失败了.
     *         -11 : 表示分配内存失败.
     *         -14 : 无效的窗口句柄
     *         -16 : 此功能依赖的驱动没有先启动
     *         -20 : 此功能不可重复加载
     *         -30 : 通信模式1和2出此错误是异常错误.
     *         -31 : 通信模式1和2出此错误是异常错误.
     *         -32 : 通信模式1和2出此错误是异常错误.
     */
    @ComMethod
    long DmGuard(int enable, String type);

    /**
     * 释放插件用的驱动. 可以自己拿去签名. 防止有人对我的签名进行检测. 强烈推荐使用驱动的用户使用. 仅释放64位系统的驱动.
     *
     * @param type 字符串: 需要释放的驱动类型. 这里写"common"即可.
     * @param path 字符串: 释放出的驱动文件全路径. 比如"c:\test.sys".
     * @return 整形数:
     *         0 : 不支持的type
     *         1 : 成功
     *         -2: 释放失败
     */
    @ComMethod
    long DmGuardExtract(String type, String path);

    /**
     * 加载用DmGuardExtract释放出的驱动. 建议自己签名后,然后找个自己喜欢的路径加载. 仅支持64位系统的驱动加载.
     * 加载成功后,就可以正常调用DmGuard了.
     *
     * @param type 字符串: 需要释放的驱动类型. 这里写"common"即可.
     * @param path 字符串:驱动文件全路径. 比如"c:\test.sys".
     * @return 整形数:
     *         返回值请参考DmGuard的返回值. 一样的含义.
     */
    @ComMethod
    long DmGuardLoadCustom(String type, String path);

    /**
     * DmGuard的加强接口,用于获取一些额外信息. 具体看下面参数介绍
     *
     * @param cmd 字符串: 盾类型. 这里取值为"gr"或者"th"(以后可能会有扩充). 这里要注意的是,如果要获取指定的盾类型信息,必须先成功用DmGuard开启此盾.比如这里的"gr"必须dm.DmGuard 1,"gr"开启成功才可以
     * @param subcmd 字符串: 针对具体的盾类型，需要获取的具体信息.
     *               如果cmd为"gr"时,那么subcmd取值如下定义:
     *               "enum" : 枚举指定进程的所有句柄.
     *               "get" : 获取指定进程的指定句柄信息.(类型,名字,权限值)
     *               "set" : 设置指定进程的指定句柄的权限值.
     *               "close": 关闭指定进程的指定句柄.
     *               如果cmd为"th"时,那么subcmd取值如下定义:
     *               "enum" : 枚举指定进程的所有线程.
     *               "get" : 获取指定线程的详细信息.(句柄值,优先级,ETHREAD,TEB,win32StartAddresss,线程地址所在的模块名,交换次数,线程状态,挂起次数)
     *               "resume" : 恢复指定的线程.不可操作本线程. 当suspend_count大于0时,每调用一次resume,都会让suspend_count减1,直到0为止才会真正的恢复线程.
     *               "suspend": 挂起指定线程.不可操作本线程.
     *               "terminate":结束指定线程.不可操作本线程.
     * @param param 字符串: 参数信息,这里具体的含义取决于cmd和subcmd. 
     *              如果cmd为"gr"时,subcmd取值为如下时，具体的参数含义:
     *              "enum" : param为"pid", pid为进程pid,10进制形式.
     *              "get" : param为"pid handle",pid为进程pid,10进制形式,handle为句柄值,10进制形式.
     *              "set" : param为"pid handle access",pid为进程pid,10进制形式,handle为句柄值,10进制形式,access为权限值,10进制形式.
     *              "close": param为"pid handle", pid为进程pid,10进制形式,handle为句柄值,10进制形式.
     *              如果cmd为"th"时,subcmd取值为如下时，具体的参数含义:
     *              "enum" : param为"pid", pid为进程pid,10进制形式.
     *              "get" : param为"tid", tid为线程tid,10进制形式. 
     *              "resume" : param为"tid", tid为线程tid,10进制形式.
     *              "suspend" : param为"tid", tid为线程tid,10进制形式.
     *              "terminate": param为"tid", tid为线程tid,10进制形式.
     * @return 字符串: 根据不同的cmd和subcmd,返回值不同.
     *         如果cmd为"gr"时,subcmd取值为如下时，具体的返回值:
     *         "enum" : "handle1|handle2|.....|handlen",每个handle都是10进制长整数. 如果失败返回空字符串
     *         "get" : "type|name|access". type表示句柄的类型，比如"Event","File"等之类的. name表示句柄的名字,有些句柄的名字可能是空的. access10进制整数,表示此句柄的权限值. 如果失败返回空字符串
     *         "set" : 成功返回"ok",否则为空字符串.
     *         "close": 成功返回"ok",否则为空字符串.
     *         如果cmd为"th"时,subcmd取值为如下时，具体的返回值:
     *         "enum" : "tid1|tid2|.....|tidn",每个tid都是10进制整数. 如果失败返回空字符串
     *         "get" : "tid|prority|ethread|teb|win32StartAddress|module_name|switch_count|state|suspend_count".如果失败返回空字符串.
     *         tid : 线程tid,10进制整数
     *         prority : 线程优先级, 10进制整数
     *         ethread : 线程内核对象ETHREAD指针. 64位16进制整数.
     *         teb : 线程内核对象TEB指针. 64位16进制整数
     *         win32StartAddress : 线程起始地址. 64位16进制整数
     *         module_name : 线程起始地址所在的模块名.
     *         switch_count : 线程切换次数. 10进制整数
     *         state : 线程状态. 10进制整数. 0 : 初始化 1 : 准备 2 : 运行 3 : 待机 4 : 结束 5 : 等待 6 : 转换. 这个地方其实只需要关心是不是4就行了. 如果是4表示线程结束了. 其它的状态都可以认为是运行状态. 不用太关心.
     *         suspend_count : 线程挂起次数. 10进制整数. 线程挂起次数,当此值大于0时,表示线程处于挂起状态. 等于0表示处于运行状态.
     *         "resume" : 成功返回"ok",否则为空字符串.
     *         "suspend": 成功返回"ok",否则为空字符串.
     *         "terminate": 成功返回"ok",否则为空字符串.
     */
    @ComMethod
    String DmGuardParams(String cmd, String subcmd, String param);

    /**
     * 卸载插件相关的所有驱动. 仅对64位系统的驱动生效.
     *
     * @return 整形数:
     *         0 : 失败
     *         1 : 成功
     */
    @ComMethod
    long UnLoadDriver();
}